#ifndef MPDATEUTILS_H
#define MPDATEUTILS_H

/******************************
 *
 * 名   称：   日期和事件有关的公共函数
 * 用   途：   timt_t转字符串 、字符串转timt_t、 获取当前时间等
 * 作用范围：   公共的
 * 创建时间：   2022-10-03
 * 参   考：
 * https://blog.csdn.net/xunmeng2002/article/details/121106051      [C++时间转换及格式化]
 * https://www.cnblogs.com/Toya/p/15559942.html
 * https://blog.csdn.net/lianshaohua/article/details/112531154
 * https://zhuanlan.zhihu.com/p/407885707
 * http://www.bytekits.com/cppstdlib/cppstdlib-put-time.html        [C++标准库格式化time_t函数std::put_time ，需要GCC5.0以上支持]
 * https://en.cppreference.com/w/cpp/chrono/c/strftime              [C++标准库格式化time_t函数std::strftime ，现使用的方案，支持低版本GCC]
 * https://blog.csdn.net/Left_Zzzz/article/details/123800975        [C/C++获取HTTP/GMT时间(gmtime)]
 * https://www.jianshu.com/p/a14c0858e9c6                           [ISO 8601：时间和日期的表示标准说明]
 * https://www.aloneguid.uk/posts/2022/03/iso-8601/
 *
 ******************************/

#include "mpConfig.h"
#include <string>

#ifdef PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif //PLATFORM_WINDOWS

#ifdef PLATFORM_WINDOWS
#ifdef _USE_32BIT_TIME_T
typedef __time32_t MP_TIME_T;
#else
typedef __time64_t MP_TIME_T;
#endif
#endif //PLATFORM_WINDOWS

#if defined(PLATFORM_UNIX)
typedef __time_t MP_TIME_T;
#endif //PLATFORM_UNIX

namespace MP{
namespace DateUtils{

/***************************************************
 * timt_t转字符串
 * *************************************************/
std::string time_to_local_date_string(const time_t& time);                  //%Y-%m-%d                      例子：2021-10-12
std::string time_to_local_datetime_string(const time_t& time);              //%Y-%m-%d %H:%M:%S             例子：2021-10-12 15:23:31
std::string time_to_local_datetime_string(const time_t& time,
                                          const std::string& format);       //自定义格式，可参考 https://en.cppreference.com/w/cpp/chrono/c/strftime
std::string time_to_gmt_string(const time_t& time);                         //%a, %d %b %Y %H:%M:%S GMT     例子：Tue, 18 Oct 2022 12:59:29 GMT
std::string time_to_gmt_string_iso8601(const time_t& time);                 //%Y%m%dT%H%M%SZ                例子：

/***************************************************
 * 字符串转timt_t
 * 方案一：通过std::strptime函数来实现，但是仅支持linux平台，windows平台中没有该函数
 * 方案二：通过std::get_time函数来实现，但是低版本的GCC不支持
 * 方案三：通过std::sscanf函数来实现，目前string_to_time函数采用，调用示例如下：
 *
 * 示例1：string_to_time("2021-10-12 15:23:31","%d-%d-%d %d:%d:%d")        result = 2021-10-12 15:23:31
 * 示例2：string_to_time("2021年10月12日","%d年%d月%d日")                    result = 2021-10-12 00:00:00
 *
 * ★ 特别提示 ：该方法要求字符串中表示时间的数字按照 年、月、日、时、分、秒 的顺序排列，不可打乱顺序或中跳过某一个，否则转换所得结果将存在不可知的错误
 *
 * *************************************************/

bool string_to_time(const std::string& str,
                    const std::string& format,
                    time_t& time);

void custom_time(time_t& time,int year,int month,int day,int hour=0, int minute=0, int second=0);

/***************************************************
 * 获取当前时间(system_clock 系统时间)
 * *************************************************/
time_t get_now_time();
std::string get_now_local_date_string();
std::string get_now_local_datetime_string();
std::string get_now_local_datetime_string_withms();
std::string get_now_local_datetime_string(const std::string& format);
std::string get_now_gmt_string();
std::string get_now_gmt_string_iso8601();

/***************************************************
 * 时间操作
 * *************************************************/

MP_TIME_T getsec_now_from_2000();
MP_TIME_T getsec_time_from_2000(const time_t& time);
bool is_now_before_time(int year,int month,int day,int hour=0, int minute=0, int second=0);

void time_add_days(time_t& time,MP_TIME_T value);
void time_add_hours(time_t& time,MP_TIME_T value);
void time_add_minutes(time_t& time,MP_TIME_T value);
void time_add_seconds(time_t& time,MP_TIME_T value);



#ifdef PLATFORM_WINDOWS

/**
 * @brief 文件时间(UTC)转为日期格式(本地)
 * @param ft
 * @param pstrDate
 * @param pstrTime
 */
std::string filetime_to_local_datetime_string(FILETIME& ft);

#endif //PLATFORM_WINDOWS

}   //END DateUtils
}   //END MP

#endif // MPDATEUTILS_H
